/*  
 * Copyright (C) 2012  	Mathieu Marleix <mathieu.marleix@aerian.fr>
 *						Doris Vaton <doris.vaton@gmail.com>
 * 
 * Based on a file of Takashi Kanamaru <kanamaru@cc.kogakuin.ac.jp>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 **/
package com.shaipicku.mjpegcams;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.GestureOverlayView.OnGesturePerformedListener;
import android.gesture.Prediction;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.SlidingDrawer;
import android.widget.TextView;
import android.widget.Toast;

import com.shaipicku.mjpegcams.armControl.ArmControl;
import com.shaipicku.mjpegcams.armControl.BluetoothDroidControlService;
import com.shaipicku.mjpegcams.armControl.DeviceListActivity;
import com.shaipicku.mjpegcams.mjpegView.MjpegInputStream;
import com.shaipicku.mjpegcams.mjpegView.MjpegView;
/**
 * Display the view with the two cameras, the slider and the gesture overlay
 * @author Mathieu Marleix <mathieu.marleix@aerian.fr>
 * @author Doris Vaton <doris.vaton@gmail.com>
 */
public class MjpegCamActivity extends Activity implements OnGesturePerformedListener {

	//gesture
	private GestureLibrary mLibrary = null;
	private Dialog dialog = null;
	protected String shape = null;
	//drawer
	private SlidingDrawer sDrawer;
	//Current color of buttons
	private ShapeData button1_shape = null, button2_shape = null, button3_shape = null;
	//Defined all data concerning the cameras
	public static int CAMERA_NUMBER = 2;

	public static int CAMERA[] = null ;
	private boolean DEBUG = true;
	private boolean popUpDisplayed = false;
	private String MODE = "";
	private static final String TAG = "MjpegActivity2";
	private String URL[] = null;
	private Locale locale = null;
	//preferences
	SharedPreferences sharedPrefs = null;

	private List<ShapeData> centerListCam1;
	private List<ShapeData> centerListCam2;
	private int[] surfaceSize;
	private boolean isLeftPresent = true, isMiddlePresent = true, isRightPresent = true;
	
	public ArmControl armControl;
	// Local Bluetooth adapter
	public BluetoothAdapter mBluetoothAdapter = null;
	// Member object for the chat services
	public BluetoothDroidControlService mCmdSendService = null;
	// Message types sent from the BluetoothChatService Handler
	public static final int MESSAGE_STATE_CHANGE = 1, MESSAGE_READ = 2, MESSAGE_WRITE = 3, MESSAGE_DEVICE_NAME = 4, MESSAGE_TOAST = 5;
	// Intent request codes
	public static final int REQUEST_CONNECT_DEVICE = 1;
	public static final int REQUEST_ENABLE_BT = 2;

	// Key names received from the BluetoothChatService Handler
	public static final String DEVICE_NAME = "device_name";
	public static final String TOAST = "toast";

	// Name of the connected device
	private String mConnectedDeviceName = null;

	/**
	 * Called at the creation of the activity
	 */
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		//Bluetooth part
		initBluetooth();

		setContentView(R.layout.cam2view); 
		sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
		String value = sharedPrefs.getString("cam_number", null);
		if(value == null)
			CAMERA_NUMBER = 2;
		else {
			try { 
				if( (CAMERA_NUMBER = Integer.valueOf(value)) > 10) throw new NumberFormatException();
			}catch (NumberFormatException e) {
				// TODO: handle exception
				Toast.makeText(MjpegCamActivity.this, getString(R.string.cam_bad_number), Toast.LENGTH_SHORT).show();
				CAMERA_NUMBER = 2;
			}

		}


		URL = new String[CAMERA_NUMBER];
		CAMERA = new int[CAMERA_NUMBER];
		for(int i = 0 ; i<CAMERA_NUMBER ; i++ ){
			CAMERA[i] = i;
			LinearLayout mjLayout = createAView(i);
			LinearLayout parent = (LinearLayout) findViewById(R.id.camParent);
			parent.addView(mjLayout);
		}


		//Retrieve informations stocked in the bundle
		Bundle param = this.getIntent().getExtras();
		this.DEBUG = (Boolean) param.getBoolean("DEBUG",false);
		setMODE((String) param.getString("MODE"));

		Button about = (Button) findViewById(R.id.about);
		about.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent intent = new Intent(MjpegCamActivity.this,StartActivity.class);
				startActivity(intent);
				finish();
			}
		});

		// Sliding drawer
		sDrawer=(SlidingDrawer)findViewById(R.id.drawer);
		if(getMODE().equals("CAMERA")){
			getsDrawer().setVisibility(View.GONE);
		}
		else if(getMODE().equals("SHAPE")){
			TextView tv = (TextView) findViewById(R.id.about);
			tv.setText(R.string.shape);
		}
		else if(getMODE().equals("COLOR")){
			TextView tv = (TextView) findViewById(R.id.about);
			tv.setText(R.string.color);
		}

		else if(getMODE().equals("SHAPE_COLOR")){
			TextView tv = (TextView) findViewById(R.id.about);
			tv.setText(R.string.shape_color);
		}
		else if(getMODE().equals("PILE_UP")){
			TextView tv = (TextView) findViewById(R.id.about);
			tv.setText(R.string.pile_up);
		}
		//Gestures
		GestureOverlayView gestureOverlayView = (GestureOverlayView)findViewById(R.id.gestures);
		gestureOverlayView.addOnGesturePerformedListener(this);
		mLibrary = GestureLibraries.fromRawResource(this, R.raw.gestures);
		if (!mLibrary.load()) {
			finish();
		}

		//Used for changing the current local of the application and so the language.
		Configuration config = getBaseContext().getResources().getConfiguration();
		String lang = sharedPrefs.getString("languages", "");
		if(DEBUG) Log.d(TAG,sharedPrefs.getString("languages", ""));
		if (! "".equals(lang) && ! config.locale.getLanguage().equals(lang))
		{
			locale = new Locale(lang);
			Locale.setDefault(locale);
			config.locale = locale;
			getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
		}

		boolean url_default = sharedPrefs.getBoolean("url_default", false);
		boolean no_url = false;
		StringBuffer sb = null;
		for(int i = 0 ; i<CAMERA_NUMBER ; i++){
			//Check if the url are stored in the preferences 
			String camURL = "cam_url"+i;
			String url = sharedPrefs.getString(camURL, "");
			//else set at the emulator loopback addresses
			if(url.equals("")){
				no_url = true;
				int camNumber = i+1;
				if(sb == null){
					sb = new StringBuffer();
					sb.append(" " + camNumber);
				}
				else
					sb.append(", " + camNumber);
			}
			//check if URL mode is activated or not
			else if(!url_default && !no_url){
				url = "http://" + url +"/?action=stream";
				setURL(url,i);
			}
			else if(!no_url)
				setURL(url,i);
			Log.i(TAG, camURL + " = " + url + "\n");
		}
		if(no_url){
			Toast.makeText(MjpegCamActivity.this, getString(R.string.cam_no_url) + " " + sb.toString(), Toast.LENGTH_SHORT).show();
			Intent intent = new Intent(this, SettingsActivity.class);
			Bundle bundle = new Bundle();
			//Add the parameters to bundle
			bundle.putBoolean("DEBUG", DEBUG);
			intent.putExtras(bundle);
			startActivity(intent);
			finish();
		}

		/**The button-choice of the screen */
		Button circle,triangle,square;
		circle = (Button) findViewById(R.id.button1);
		triangle = (Button) findViewById(R.id.button2);
		square = (Button) findViewById(R.id.button3);

		/** Set of clickListener on the different buttons **/
		circle.setOnClickListener(new ClickListener_Button());
		triangle.setOnClickListener(new ClickListener_Button());
		square.setOnClickListener(new ClickListener_Button());

		setArmControl(new ArmControl(MjpegCamActivity.this));
	}
	/**
	 * Initialize the Bluetooth on the device
	 */
	public void initBluetooth() {
		// Get local Bluetooth adapter
		mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

		// If the adapter is null, then Bluetooth is not supported
		if (mBluetoothAdapter == null) {
			Toast.makeText(MjpegCamActivity.this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
			finish();
			return;
		}
	}

	/**
	 * Call when the activity is displayed
	 */
	public void onResume() {
		super.onResume();
		if(DEBUG) Log.d(TAG,"onResume()");

		for(int i = 0; i<CAMERA_NUMBER;i++ ){
			MjpegView mjpegView = (MjpegView) findViewById(66642+i);
			new DoRead(CAMERA[i]).execute(getURL()[i]);
			if(mjpegView == null) ;
			else {
				mjpegView.resumePlayback();
				mjpegView.setVisibility(View.VISIBLE);
			}
		}

		// Performing this check in onResume() covers the case in which BT was
		// not enabled during onStart(), so we were paused to enable it...
		// onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
		if (mCmdSendService != null) {
			// Only if the state is STATE_NONE, do we know that we haven't started already
			if (mCmdSendService.getState() == BluetoothDroidControlService.STATE_NONE) {
				// Start the Bluetooth chat services
				mCmdSendService.start();
			}
		}
	}
	/**
	 * Call at the first start of the activity
	 */
	public void onStart() {
		super.onStart();
		if(DEBUG){
			Log.d(TAG,"onStart()");
			for(int i = 0 ; i<CAMERA_NUMBER ; i++){
				MjpegView mjpegView = (MjpegView) findViewById(66642+i);
				mjpegView.setDEBUG(DEBUG);
			}
		}
		TextView tv = (TextView) findViewById(R.id.noflux);
		tv.setVisibility(View.GONE);
		tv.setText("");

		//Set Bluetooth
		// If BT is not on, request that it be enabled.
		// setupChat() will then be called during onActivityResult
		if (!mBluetoothAdapter.isEnabled()) {
			Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
			startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
			// Otherwise, setup the chat session
		} else {
			if (mCmdSendService == null) setupBT();
		}
	}
	
	/**
	 * Initialize the bluetooth service before using it 
	 */
	public void setupBT() {
		// Initialize the BluetoothChatService to perform bluetooth connections
		mCmdSendService = new BluetoothDroidControlService(this, mHandler);
	}


	/**
	 * Call when the activity is set as not active
	 */
	public void onPause() {
		super.onPause();
		if(DEBUG) Log.d(TAG,"onPause()");

		for(int i = 0 ; i < CAMERA_NUMBER ; i++){
			MjpegView mjpegView = (MjpegView) findViewById(66642+i);
			if(mjpegView == null) ;
			else {
				mjpegView.stopPlayback();
				mjpegView.setVisibility(View.GONE);
			}
		}
		TextView tv = (TextView) findViewById(R.id.noflux);
		tv.setVisibility(View.GONE);
		tv.setText("");
	}
	/**
	 * Call before the activity is destroy
	 */
	public void onStop() {
		if(DEBUG) Log.d(TAG,"onStop()");
		super.onStop();
		TextView tv = (TextView) findViewById(R.id.noflux);
		tv.setVisibility(View.GONE);
		tv.setText("");
	}
	/**
	 * Call at the destruction of the activity
	 */
	public void onDestroy() {
		if(DEBUG) Log.d(TAG,"onDestroy()");
		super.onDestroy();
		TextView tv = (TextView) findViewById(R.id.noflux);
		tv.setVisibility(View.GONE);
		tv.setText("");
		LogCat.flushLog(this);
		// Stop the Bluetooth chat services
		if (mCmdSendService != null) mCmdSendService.stop();
	}

	/**
	 * Task in background which actualize the display of the camera 	 *
	 */
	public class DoRead extends AsyncTask<String, Void, MjpegInputStream> {

		private final Exception Exception = null;
		int camera_id;
		//Pop-up for the loading
		ProgressDialog mProgressDialog = null;

		public DoRead(int camera_id){
			this.camera_id = camera_id;
		}

		protected MjpegInputStream doInBackground(String... url) {
			//TODO: if camera has authentication deal with it and don't just not work
			runOnUiThread(new Runnable() {
				@Override
				public void run() {
					mProgressDialog = ProgressDialog.show(MjpegCamActivity.this,getString(R.string.cam2),getString(R.string.loading),true);
					mProgressDialog.setCancelable(true);
				}
			});
			HttpResponse res = null;
			DefaultHttpClient httpclient = new DefaultHttpClient();     
			if(DEBUG) Log.d(TAG, "1. Sending http request");
			try {
				res = httpclient.execute(new HttpGet(URI.create(url[0])));
				if(mProgressDialog != null ) mProgressDialog.dismiss(); //d?
				if(DEBUG) Log.d(TAG, "2. Request finished, status = " + res.getStatusLine().getStatusCode());
				if(res.getStatusLine().getStatusCode()==401){
					//You must turn off camera User Access Control before this will work
					return null;
				}
				return new MjpegInputStream(res.getEntity().getContent(),DEBUG);  
			} catch (ClientProtocolException e) {
				e.printStackTrace();
				if(DEBUG) Log.d(TAG, "Request failed-ClientProtocolException", e);
				runOnUiThread(new Runnable() {
					@Override
					public void run() {
						TextView tv = (TextView) findViewById(R.id.noflux);
						if(mProgressDialog != null ) mProgressDialog.dismiss();
						tv.append("\n" +getString(R.string.timed_out));
						tv.setVisibility(View.VISIBLE);
					}
				});
				//Error connecting to camera
			} catch (IOException e) {
				e.printStackTrace();
				if(DEBUG) Log.d(TAG, "Request failed-IOException", e);
				runOnUiThread(new Runnable() {
					@Override
					public void run() {
						TextView tv = (TextView) findViewById(R.id.noflux);
						if(mProgressDialog != null ) mProgressDialog.dismiss();
						tv.append("\n" +getString(R.string.timed_out));
						tv.setVisibility(View.VISIBLE);
					}
				});
				//Error connecting to camera
			} catch (Exception e) {
				// TODO: handle exception
				if(DEBUG) Log.d(TAG, "Bad URL", e);
			}

			return null;
		}
		/**
		 * Call at the result of the precedent void, launch the mjpegView with the data of the MjpegInputView
		 */
		protected void onPostExecute(MjpegInputStream result) {
			if(mProgressDialog != null ) mProgressDialog.dismiss();
			if(DEBUG) Log.d(TAG,"1. Post excution");
			//Check what is the current cam
			int i = camera_id;
			int current_id = 66642+i;
			MjpegView mjpegView = (MjpegView) findViewById(current_id);
			if(result != null) {
				if(mjpegView == null) Log.e(TAG,"Mjpegview " + current_id + " null");
				else {
					mjpegView.setSource(result);
					mjpegView.setMODE(getMODE());
					mjpegView.setMjpeg2(MjpegCamActivity.this);
					mjpegView.setCamId(CAMERA[i]);
					mjpegView.showFps(true);
					try {
						Bitmap bm = result.readMjpegFrame();;
						int j = 0;
						while(bm == null && result != null){
							bm = result.readMjpegFrame();
							if(j == 500) throw Exception;
							j++;
						}
						mjpegView.setLayoutParams(new LayoutParams(mjpegView.getWidth(),bm.getHeight()*mjpegView.getWidth()/bm.getWidth()));
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (Exception e) {
						// TODO Auto-generated catch block
						TextView tv = (TextView) findViewById(R.id.noflux);
						if(getURL()[i].equals("") || getURL()[i].equals("10.0.2.2:8080"))
							tv.append("\n"+getString(R.string.cam_url_error_default) + "8080" );
						else
							tv.append("\n"+getString(R.string.cam_url_error) + " " + getURL()[i]);
						tv.setVisibility(View.VISIBLE);
					}
				}
			}
			else {
				TextView tv = (TextView) findViewById(R.id.noflux);
				if(getURL()[i].equals("") || getURL()[i].equals("10.0.2.2:8080"))
					tv.append("\n"+getString(R.string.cam_url_error_default) + "8080" );
				else
					tv.append("\n"+getString(R.string.cam_url_error) + " " + getURL()[i]);
				tv.setVisibility(View.VISIBLE);
			}
		}
	}

	/**
	 * Generate the menu.
	 */
	public boolean onCreateOptionsMenu(Menu menu) {
		// refresh the tabs and their content
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.menumjpegview, menu);
		return true;
	}
	/**
	 * Listener of the menu.
	 */
	public boolean onOptionsItemSelected(MenuItem item) {
		Intent intent;
		Bundle bundle;
		switch (item.getItemId()) {
		case R.id.option:
			intent = new Intent(this, SettingsActivity.class);
			bundle = new Bundle();
			//Add the parameters to bundle as
			bundle.putBoolean("DEBUG", DEBUG);
			intent.putExtras(bundle);
			startActivity(intent);
			finish();
			return true;
		case R.id.connect:
			// Launch the DeviceListActivity to see devices and do scan
			Intent serverIntent = new Intent(this, DeviceListActivity.class);
			startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
			return true;
		case R.id.disconnect:
			// Stop the Bluetooth chat services
			if (mCmdSendService != null) mCmdSendService.stop();
			return true;
		case R.id.init:	
			getArmControl().initializeMotors();
			return true;
		case R.id.main:
			finish();
			return true;
		case R.id.logcat:
			intent = new Intent(this, LogCat.class);
			startActivity(intent);
			finish();
		}
		return false;
	}
	/**
	 * Call when the device receive bluetooth data from the PIC
	 */
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (requestCode) {
		case REQUEST_CONNECT_DEVICE:
			// When DeviceListActivity returns with a device to connect
			if (resultCode == Activity.RESULT_OK) {
				// Get the device MAC address
				String address = data.getExtras()
						.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
				// Get the BLuetoothDevice object
				BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
				// Attempt to connect to the device
				mCmdSendService.connect(device);
			}
			break;
		case REQUEST_ENABLE_BT:
			// When the request to enable Bluetooth returns
			if (resultCode == Activity.RESULT_OK) {
				// Bluetooth is now enabled, so set up a chat session
				setupBT();
			} else {
				// User did not enable Bluetooth or an error occured
				Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
				finish();
			}
		}
	}


	// The Handler that gets information back from the BluetoothChatService
	public final Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			TextView mTitle = (TextView) findViewById(R.id.title_right_text);
			switch (msg.what) {
			case MESSAGE_STATE_CHANGE:
				switch (msg.arg1) {
				case BluetoothDroidControlService.STATE_CONNECTED:
					mTitle.setText(R.string.title_connected_to);
					mTitle.append(mConnectedDeviceName);
					getArmControl().initializeMotors();
					break;
				case BluetoothDroidControlService.STATE_CONNECTING:
					mTitle.setText(R.string.title_connecting);
					break;
				case BluetoothDroidControlService.CONNECTION_LOST:
					mTitle.setText(R.string.connectionLost);
					getArmControl().initializeMotors();
					break;
				case BluetoothDroidControlService.UNABLE_TO_CONNECT:
					mTitle.setText(R.string.connectionUnable);
					getArmControl().initializeMotors();
					break;
				case BluetoothDroidControlService.STATE_LISTEN:
				case BluetoothDroidControlService.STATE_NONE:
					mTitle.setText(R.string.title_not_connected);
					break;
				}
				break;
			case MESSAGE_WRITE:
				//                byte[] writeBuf = (byte[]) msg.obj;
				// construct a string from the buffer
				//                String writeMessage = new String(writeBuf);
				//                mConversationArrayAdapter.add("Me:  " + writeMessage);
				break;
			case MESSAGE_READ:
				//				byte[] readBuf = (byte[]) msg.obj;
				// construct a string from the valid bytes in the buffer
				//				String readMessage = new String(readBuf, 0, msg.arg1);
				//				Log.d(TAG,readMessage);
				//                mConversationArrayAdapter.add(mConnectedDeviceName+":  " + readMessage);
				break;
			case MESSAGE_DEVICE_NAME:
				// save the connected device's name
				mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
				Toast.makeText(MjpegCamActivity.this, "Connected to "
						+ mConnectedDeviceName, Toast.LENGTH_SHORT).show();
				break;
			case MESSAGE_TOAST:
				Toast.makeText(MjpegCamActivity.this, msg.getData().getString(TOAST),
						Toast.LENGTH_SHORT).show();
				break;
			}
		}
	};


	/**
	 * Sends a message.
	 * @param message  A string of text to send.
	 */
	public int sendMessage(String message) {
		// Check that we're actually connected before trying anything
		if (mCmdSendService.getState() != BluetoothDroidControlService.STATE_CONNECTED) {
			return -1;
		}

		// Check that there's actually something to send
		if (message.length() > 0) {
			// Get the message bytes and tell the BluetoothChatService to write
			byte[] send = message.getBytes();
			if(send.length==3){
				mCmdSendService.write(send);
				return 0;
			}
		}
		return -2;
	}

	/** 
	 * Class defining what happened when the user clicks on a shape button 
	 */
	class ClickListener_Button implements Button.OnClickListener{
		ShapeData sd = null;
		@Override
		public void onClick(View button) {

			AlertDialog.Builder messageBox = new AlertDialog.Builder(MjpegCamActivity.this);	

			/** Check which button was selected and return the string of the shape selected **/

			switch(button.getId()){
			case R.id.button1:
				sd = getButton1_shape();
				break;

			case R.id.button2:
				sd = getButton2_shape();
				break;

			case R.id.button3:
				sd = getButton3_shape();
				break;
			}  

			if(sd.getShape() == ShapeData.TRIANGLE)
				messageBox.setMessage(getString(R.string.triangle));
			else if(sd.getShape() == ShapeData.SQUARE)
				messageBox.setMessage(getString(R.string.square));
			else if(sd.getShape() == ShapeData.CIRCLE)
				messageBox.setMessage(getString(R.string.circle));

			/** 
			 * Display of an alert box asking for confirmation of the chosen shape 
			 * If it's yes so the NEXT STEP is for the arm to point at the right shape
			 * It it's no the user chose an another shape
			 */
			messageBox.setPositiveButton(android.R.string.yes, 
					new DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {
					// TODO Auto-generated method stub
					runOnUiThread(new Runnable() {
						@Override
						public void run() {
							if(getMODE().equals("SHAPE"))
								actionPerformed(sd.getShape());
							else if(getMODE().equals("COLOR")){
								actionPerformed(sd.getColor());
							}
							else if(getMODE().equals("SHAPE_COLOR")){
								actionPerformed(sd.getColor(),sd.getShape());
							}
							else if(getMODE().equals("PILE_UP")){
								actionPerformed(sd.getColor());
							}
						}
					});
				}
			});
			messageBox.setNegativeButton(android.R.string.no, 
					new DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {
					// TODO Auto-generated method stub
					runOnUiThread(new Runnable() {
						@Override
						public void run() {
							Toast.makeText(MjpegCamActivity.this,getString(R.string.redo),Toast.LENGTH_SHORT).show();
						}
					});
				}
			});
			messageBox.show();
		}
	}

	/**
	 * Contain the Gesture Overlay part which recognize the shape drawn by comparison with the gesture
	 * file contains in raw.
	 */
	public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
		ArrayList<Prediction> predictions = mLibrary.recognize(gesture);
		// Send the most similar form recognized
		if (predictions.size() > 0 && predictions.get(0).score > 1.0) {
			setShape(predictions.get(0).name);
			//pop-up of the shape's validation
			dialog = new Dialog(this);
			dialog.setContentView(R.layout.drawdialog);
			dialog.setTitle(getString(R.string.shapeTitle));
			dialog.setCancelable(true);

			//set up button
			Button buttonOk = (Button) dialog.findViewById(R.id.ButtonOk);
			buttonOk.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					//if the ok button is pushed, it close the pop-up, the slidingDraw and display a Toast. 
					dialog.dismiss();
					runOnUiThread(new Runnable() {
						@Override
						public void run() {
							if(MjpegCamActivity.this.getShape().equals("circle")){
								if(getMODE().equals("SHAPE"))
									actionPerformed(ShapeData.CIRCLE);
								else if(getMODE().equals("COLOR")){
									if(getButton1_shape().getShape() == ShapeData.CIRCLE)
										actionPerformed(getButton1_shape().getColor());
									else if(getButton2_shape().getShape() == ShapeData.CIRCLE)
										actionPerformed(getButton2_shape().getColor());
									else if(getButton3_shape().getShape() == ShapeData.CIRCLE)
										actionPerformed(getButton3_shape().getColor());
								}
								else if(getMODE().equals("SHAPE_COLOR")){
									if(getButton1_shape().getShape() == ShapeData.CIRCLE)
										actionPerformed(getButton1_shape().getColor(),getButton1_shape().getShape());
									else if(getButton2_shape().getShape() == ShapeData.CIRCLE)
										actionPerformed(getButton2_shape().getColor(),getButton2_shape().getShape());
									else if(getButton3_shape().getShape() == ShapeData.CIRCLE)
										actionPerformed(getButton3_shape().getColor(),getButton3_shape().getShape());
								}
								else if(getMODE().equals("PILE_UP")){
									if(getButton1_shape().getShape() == ShapeData.CIRCLE)
										actionPerformed(getButton1_shape().getColor());
									else if(getButton2_shape().getShape() == ShapeData.CIRCLE)
										actionPerformed(getButton2_shape().getColor());
									else if(getButton3_shape().getShape() == ShapeData.CIRCLE)
										actionPerformed(getButton3_shape().getColor());
								}
							}
							else if(MjpegCamActivity.this.getShape().equals("square")){
								if(getMODE().equals("SHAPE"))
									actionPerformed(ShapeData.SQUARE);
								else if(getMODE().equals("COLOR")){
									if(getButton1_shape().getShape() == ShapeData.SQUARE)
										actionPerformed(getButton1_shape().getColor());
									else if(getButton2_shape().getShape() == ShapeData.SQUARE)
										actionPerformed(getButton2_shape().getColor());
									else if(getButton3_shape().getShape() == ShapeData.SQUARE)
										actionPerformed(getButton3_shape().getColor());
								}
								else if(getMODE().equals("SHAPE_COLOR")){
									if(getButton1_shape().getShape() == ShapeData.SQUARE)
										actionPerformed(getButton1_shape().getColor(),getButton1_shape().getShape());
									else if(getButton2_shape().getShape() == ShapeData.SQUARE)
										actionPerformed(getButton2_shape().getColor(),getButton2_shape().getShape());
									else if(getButton3_shape().getShape() == ShapeData.SQUARE)
										actionPerformed(getButton3_shape().getColor(),getButton3_shape().getShape());
								}
								else if(getMODE().equals("PILE_UP")){
									if(getButton1_shape().getShape() == ShapeData.SQUARE)
										actionPerformed(getButton1_shape().getColor());
									else if(getButton2_shape().getShape() == ShapeData.SQUARE)
										actionPerformed(getButton2_shape().getColor());
									else if(getButton3_shape().getShape() == ShapeData.SQUARE)
										actionPerformed(getButton3_shape().getColor());
								}
							}
							else if(MjpegCamActivity.this.getShape().equals("triangle")){
								if(getMODE().equals("SHAPE"))
									actionPerformed(ShapeData.TRIANGLE);
								else if(getMODE().equals("COLOR")){
									if(getButton1_shape().getShape() == ShapeData.TRIANGLE)
										actionPerformed(getButton1_shape().getColor());
									else if(getButton2_shape().getShape() == ShapeData.TRIANGLE)
										actionPerformed(getButton2_shape().getColor());
									else if(getButton3_shape().getShape() == ShapeData.TRIANGLE)
										actionPerformed(getButton3_shape().getColor());

								}
								else if(getMODE().equals("SHAPE_COLOR")){
									if(getButton1_shape().getShape() == ShapeData.TRIANGLE)
										actionPerformed(getButton1_shape().getColor(),getButton1_shape().getShape());
									else if(getButton2_shape().getShape() == ShapeData.TRIANGLE)
										actionPerformed(getButton2_shape().getColor(),getButton2_shape().getShape());
									else if(getButton3_shape().getShape() == ShapeData.TRIANGLE)
										actionPerformed(getButton3_shape().getColor(),getButton3_shape().getShape());
								}
								else if(getMODE().equals("PILE_UP")){
									if(getButton1_shape().getShape() == ShapeData.TRIANGLE)
										actionPerformed(getButton1_shape().getColor());
									else if(getButton2_shape().getShape() == ShapeData.TRIANGLE)
										actionPerformed(getButton2_shape().getColor());
									else if(getButton3_shape().getShape() == ShapeData.TRIANGLE)
										actionPerformed(getButton3_shape().getColor());
								}
							}
						}
					});
				}
			});
			//If the cancel button is push, it close the op-up and invite to redo the draw.
			Button buttonCancel = (Button) dialog.findViewById(R.id.ButtonCancel);
			buttonCancel.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					dialog.dismiss();
				}
			});

			if(getShape().equals("circle")){
				//set up image view
				ImageView img = (ImageView) dialog.findViewById(R.id.shapeImage);
				img.setImageResource(R.drawable.circle_off);
				img.setContentDescription(getShape());
				dialog.show();
			}
			else if(getShape().equals("square")){
				//set up image view
				ImageView img = (ImageView) dialog.findViewById(R.id.shapeImage);
				img.setImageResource(R.drawable.square_off);
				img.setContentDescription(getShape());
				dialog.show();
			}
			else if(getShape().equals("triangle")){
				//set up image view
				ImageView img = (ImageView) dialog.findViewById(R.id.shapeImage);
				img.setImageResource(R.drawable.triangle_off);
				img.setContentDescription(getShape());
				dialog.show();
			}

		}
		else Toast.makeText(this,getString(R.string.retry) , Toast.LENGTH_LONG).show();
	}
	// If the drawer is open, pressing the key back will close it.
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if ((keyCode == KeyEvent.KEYCODE_BACK)) {
			if(getsDrawer().isOpened() == true){
				getsDrawer().animateClose();	
			}else{
				Intent intent = new Intent(MjpegCamActivity.this,StartActivity.class);
				startActivity(intent);
				finish();
			}
		}return false;
	}
	/**
	 * Launch the action when the result button is pressed
	 * @param type the type of the shape/color selected
	 */
	public void actionPerformed(final int type){
		switch (type) {
		case  ShapeData.CIRCLE :
			if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
				Toast.makeText(MjpegCamActivity.this,getString(R.string.armMoving) + " " + getString(R.string.circle_shape) + "\n", Toast.LENGTH_LONG).show();
			break;
		case ShapeData.TRIANGLE :
			if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
				Toast.makeText(MjpegCamActivity.this,getString(R.string.armMoving) + " " + getString(R.string.triangle_shape) + "\n", Toast.LENGTH_LONG).show();
			break;
		case ShapeData.SQUARE :
			if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
				Toast.makeText(MjpegCamActivity.this,getString(R.string.armMoving) + " " + getString(R.string.square_shape) + "\n",Toast.LENGTH_SHORT).show();
			break;
		case ShapeData.RED :
			if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
				Toast.makeText(MjpegCamActivity.this,getString(R.string.armMoving) + " " + getString(R.string.red_color) + "\n",Toast.LENGTH_SHORT).show();
			break;
		case ShapeData.GREEN :
			if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
				Toast.makeText(MjpegCamActivity.this,getString(R.string.armMoving) + " " + getString(R.string.green_color) + "\n",Toast.LENGTH_SHORT).show();
			break;
		case ShapeData.BLUE :
			if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
				Toast.makeText(MjpegCamActivity.this,getString(R.string.armMoving) + " " + getString(R.string.blue_color) + "\n",Toast.LENGTH_SHORT).show();
		default:
			break;
		}
		Thread thread = new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				getsDrawer().setFocusable(false);
				if(getMODE().equals("PILE_UP")){
					sendControlPileUp(type);
				}
				else sendControl(type);
				if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED && !getMODE().equals("PILE_UP"))
					MjpegView.setUpdateConfiguration(true);
			}
		});
		thread.start();
		getsDrawer().close();
		getsDrawer().lock();
	}
	/**
	 * Set the center of the arm (deprecated)
	 * @param Cam_Id
	 * @param centerList
	 * @param surfaceSize
	 */
	public void setCenterList(int Cam_Id, List<ShapeData> centerList, int[] surfaceSize){
		setSurfaceSize(surfaceSize);
		if(Cam_Id == CAMERA[0])
			setCenterListCam1(centerList);
		else
			setCenterListCam2(centerList);
	}
	/**
	 * Get the center of the arm (deprecated)
	 * @param integer Cam_Id
	 * @return int[] The coordinates of the center
	 */
	public int[] getCenterCoordinate(int Cam_Id){
		int point[] = {0,0};
		int numberofShape = 0;
		List<ShapeData> list;

		if(Cam_Id == CAMERA[0])
			list = getCenterListCam1();
		else list = getCenterListCam2();

		for(ShapeData sd : list){
			point[0] += sd.getX();
			point[1] += sd.getY();
			numberofShape++;
		}

		if(numberofShape != 0){
			point[0] = point[0]/numberofShape;
			point[1] = point[1]/numberofShape;
		}
		return point;
	}
	/**
	 * Launch the action when the result button is pressed
	 * @param final integer color the color selected
	 * @param final integer shape the shape selected
	 */
	public void actionPerformed(final int color,final  int shape){
		if(color == ShapeData.GREEN && shape == ShapeData.CIRCLE){
			runOnUiThread(new Thread(new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
						Toast.makeText(MjpegCamActivity.this,getString(R.string.armMoving) + " " + getString(R.string.green_circle_shape) + "\n",Toast.LENGTH_SHORT).show();
				}
			}));
		}
		else if(color == ShapeData.GREEN && shape == ShapeData.SQUARE){
			runOnUiThread(new Thread(new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
						Toast.makeText(MjpegCamActivity.this,getString(R.string.armMoving) + " " + getString(R.string.green_square_shape) + "\n",Toast.LENGTH_SHORT).show();
				}
			}));
		}
		else if(color == ShapeData.GREEN && shape == ShapeData.TRIANGLE){
			runOnUiThread(new Thread(new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
						Toast.makeText(MjpegCamActivity.this,getString(R.string.armMoving) + " " + getString(R.string.green_triangle_shape) + "\n",Toast.LENGTH_SHORT).show();
				}
			}));
		}
		else if(color == ShapeData.RED && shape == ShapeData.CIRCLE){
			// TODO Auto-generated method stub
			runOnUiThread(new Thread(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
						Toast.makeText(MjpegCamActivity.this,getString(R.string.armMoving) + " " + getString(R.string.red_circle_shape) + "\n",Toast.LENGTH_SHORT).show();
				}
			}));
		}
		else if(color == ShapeData.RED && shape == ShapeData.SQUARE){
			runOnUiThread(new Thread(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
						Toast.makeText(MjpegCamActivity.this,getString(R.string.armMoving) + " " + getString(R.string.red_square_shape) + "\n",Toast.LENGTH_SHORT).show();
				}
			}));
		}
		else if(color == ShapeData.RED && shape == ShapeData.TRIANGLE){
			runOnUiThread(new Thread(new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
						Toast.makeText(MjpegCamActivity.this,getString(R.string.armMoving) + " " + getString(R.string.red_triangle_shape) + "\n",Toast.LENGTH_SHORT).show();
				}
			}));
		}
		else if(color == ShapeData.BLUE && shape == ShapeData.CIRCLE){
			runOnUiThread(new Thread(new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
						Toast.makeText(MjpegCamActivity.this,getString(R.string.armMoving) + " " + getString(R.string.blue_circle_shape) + "\n",Toast.LENGTH_SHORT).show();
				}
			}));
		}
		else if(color == ShapeData.BLUE && shape == ShapeData.SQUARE){
			runOnUiThread(new Thread(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
						Toast.makeText(MjpegCamActivity.this,getString(R.string.armMoving) + " " + getString(R.string.blue_square_shape) + "\n",Toast.LENGTH_SHORT).show();
				}
			}));
		}
		else if(color == ShapeData.BLUE && shape == ShapeData.TRIANGLE){
			runOnUiThread(new Thread(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
						Toast.makeText(MjpegCamActivity.this,getString(R.string.armMoving) + " " + getString(R.string.blue_triangle_shape) + "\n",Toast.LENGTH_SHORT).show();
				}
			}));
		}
		Thread thread = new Thread(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				getsDrawer().setFocusable(false);
				sendControl(color,shape);
				if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
					MjpegView.setUpdateConfiguration(true);
			}
		});
		thread.start();
		getsDrawer().close();
		getsDrawer().setFocusable(false);
	}
	/**
	 * Send information to the ArmControl class
	 * @param integer type
	 */
	public void sendControl(int type){
		int start = -1, end = -1;

		MjpegView mjpeg1 = (MjpegView) findViewById(66642);
		int middle[] = mjpeg1.getMIDDLE();
		int left[] = mjpeg1.getLEFT();
		int right[] = mjpeg1.getRIGHT();

		if(middle[0] == type && isMiddlePresent || middle[1] == type && isMiddlePresent ){
			start = ArmControl.MIDDLE;
			isMiddlePresent = false;
		}
		else if(left[0] == type && isLeftPresent || left[1] == type && isLeftPresent){
			start = ArmControl.LEFT;
			isLeftPresent = false;
		}
		else if(right[0] == type && isRightPresent || right[1] == type && isRightPresent){
			start = ArmControl.RIGHT;
			isRightPresent = false;
		}
		else {
			runOnUiThread(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					Toast.makeText(MjpegCamActivity.this, getString(R.string.gameFinished), Toast.LENGTH_SHORT);
				}
			});
			return;
		}

		MjpegView mjpeg2 = (MjpegView) findViewById(66643);
		middle = mjpeg2.getMIDDLE();
		left = mjpeg2.getLEFT();

		if(middle[0] == type || middle[1] == type)
			end = ArmControl.MIDDLE;
		else if(left[0] == type || left[1] == type)
			end = ArmControl.LEFT;
		else
			end = ArmControl.RIGHT;

		getArmControl().armMove(start, end);
	}	
	/**
	 * Send information to the ArmControl class if you're in PileUp Mode
	 * @param integer type
	 */
	public void sendControlPileUp(int type){
		int start = -1;

		MjpegView mjpeg1 = (MjpegView) findViewById(66642);
		final int middle[] = mjpeg1.getMIDDLE();
		final int left[] = mjpeg1.getLEFT();
		final int right[] = mjpeg1.getRIGHT();

		if(middle[0] == type && isMiddlePresent || middle[1] == type && isMiddlePresent ){
			start = ArmControl.MIDDLE;
			isMiddlePresent = false;
			runOnUiThread(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED){
						Toast.makeText(MjpegCamActivity.this, getString(R.string.armMoving) + " " + ShapeData.getLabel(middle[0]), Toast.LENGTH_SHORT);
						findViewById(R.id.button2).setVisibility(View.GONE);
					}
				}
			});
		}
		else if(left[0] == type && isLeftPresent || left[1] == type && isLeftPresent){
			start = ArmControl.LEFT;
			isLeftPresent = false;
			runOnUiThread(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED){
						Toast.makeText(MjpegCamActivity.this, getString(R.string.armMoving) + " " + ShapeData.getLabel(left[0]), Toast.LENGTH_SHORT);
						findViewById(R.id.button1).setVisibility(View.GONE);
					}
				}
			});
		}
		else if(right[0] == type && isRightPresent || right[1] == type && isRightPresent){
			start = ArmControl.RIGHT;
			isRightPresent = false;
			runOnUiThread(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED){
						Toast.makeText(MjpegCamActivity.this, getString(R.string.armMoving) + " " + ShapeData.getLabel(right[0]), Toast.LENGTH_SHORT);
						findViewById(R.id.button3).setVisibility(View.GONE);
					}
				}
			});
		}
		else {
			runOnUiThread(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					Toast.makeText(MjpegCamActivity.this, getString(R.string.gameFinished), Toast.LENGTH_SHORT);
				}
			});
			return;
		}

		getArmControl().pileUp(start);

		if(findViewById(R.id.button1).getVisibility() == View.GONE && findViewById(R.id.button2).getVisibility() == View.GONE && findViewById(R.id.button3).getVisibility() == View.GONE){

			runOnUiThread(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					TextView tv = (TextView) findViewById(R.id.choice_text);
					tv.setText(getString(R.string.shape_choice)+"\n"+getString(R.string.gameFinished));
				}
			});
		}
	}	
	/**
	 * Send informations to the ArmControl class
	 * @param integer color
	 * @param integer shape
	 */
	public void sendControl(int color, int shape){
		int start = -1, end = -1;
		MjpegView mjpeg1 = (MjpegView) findViewById(66642);
		int middle[] = mjpeg1.getMIDDLE();
		int left[] = mjpeg1.getLEFT();
		int right[] = mjpeg1.getRIGHT();

		if(middle[0] == color && middle[1] == shape && isMiddlePresent){
			start = ArmControl.MIDDLE;
			isMiddlePresent = false;
			if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
				setButtonBackground(new ShapeData(ShapeData.NOTHING, ShapeData.NOTHING, 0, 0),CAMERA[0] , R.id.button2);
		}
		else if(left[0] == color && left[1] == shape && isLeftPresent){
			start = ArmControl.LEFT;
			isLeftPresent = false;
			if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
				setButtonBackground(new ShapeData(ShapeData.NOTHING, ShapeData.NOTHING, 0, 0),CAMERA[0] , R.id.button1);
		}
		else if(right[0] == color && right[1] == shape && isRightPresent) {
			start = ArmControl.RIGHT;
			isRightPresent = false;
			if(mCmdSendService.getState() == BluetoothDroidControlService.STATE_CONNECTED)
				setButtonBackground(new ShapeData(ShapeData.NOTHING, ShapeData.NOTHING, 0, 0),CAMERA[0] , R.id.button3);
		}
		else {
			runOnUiThread(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					Toast.makeText(MjpegCamActivity.this, getString(R.string.gameFinished), Toast.LENGTH_SHORT);
				}
			});
			return;
		}

		MjpegView mjpeg2 = (MjpegView) findViewById(66643);
		middle = mjpeg2.getMIDDLE();
		left = mjpeg2.getLEFT();

		if(middle[0] == color && middle[1] == shape)
			end = ArmControl.MIDDLE;
		else if(left[0] == color && left[1] == shape)
			end = ArmControl.LEFT;
		else
			end = ArmControl.RIGHT;

		getArmControl().armMove(start, end);
	}
	/**
	 * Get coordinates of a shape in mode Shape and Color
	 * @param integer mjpegview_id
	 * @param integer color
	 * @param integer shape
	 * @return int[] the coordinates of the shape
	 */
	public int[] getCoordinate(int mjpegview_id,int color, int shape){
		int numberofShape = 0, point[] = {0,0};
		List<ShapeData> temp = new ArrayList<ShapeData>();
		List<ShapeData> list = new ArrayList<ShapeData>();

		//Start coordinate
		MjpegView mjpegview = (MjpegView) findViewById(mjpegview_id);
		if(mjpegview == null) ;
		else {
			if(color == ShapeData.BLUE){
				temp.addAll(mjpegview.getListOfShapeBlue());
				for(ShapeData sd : temp){
					if(sd.getShape() == shape){
						list.add(sd);
					}
				}
			}
			else if(color == ShapeData.GREEN){
				temp.addAll(mjpegview.getListOfShapeGreen());
				for(ShapeData sd : temp){
					if(sd.getShape() == shape){
						list.add(sd);
					}
				}
			}
			else if(color == ShapeData.RED){
				temp.addAll(mjpegview.getListOfShapeRed());
				for(ShapeData sd : temp){
					if(sd.getShape() == shape){
						list.add(sd);
					}
				}
			}

			temp.clear();
			temp = null;

			for(ShapeData sd : list){
				point[0] += sd.getX();
				point[1] += sd.getY();
				numberofShape++;
			}

			if(numberofShape != 0){
				point[0] = point[0]/numberofShape;
				point[1] = point[1]/numberofShape;
			}
		}
		if(numberofShape > 0){
			return point;

		}
		else return null;
	}
	/**
	 * Get coordinates of a shape in mode Shape or mode Color
	 * @param integer mjpegview_id
	 * @param integer type
	 * @return int[] the coordinates of the shape
	 */
	public int[] getCoordinate(int mjpegview_id,int type){
		if(getMODE().equals("SHAPE")){
			int numberofShape = 0, point[] = {0,0};
			List<ShapeData> temp = new ArrayList<ShapeData>();
			List<ShapeData> list = new ArrayList<ShapeData>();

			//Start coordinate
			MjpegView mjpegview = (MjpegView) findViewById(mjpegview_id);
			if(mjpegview == null) ;
			else {
				list.clear();
				temp.addAll(mjpegview.getListOfShapeBlue());
				for(ShapeData sd : temp){
					if(sd.getShape() == type){
						list.add(sd);
					}
				}
				if(list.size() <= temp.size()/2){
					temp.clear();
					list.clear();
					temp.addAll(mjpegview.getListOfShapeGreen());
					for(ShapeData sd : temp){
						if(sd.getShape() == type){
							list.add(sd);
						}
					}
				}
				if(list.size() <= temp.size()/2){
					temp.clear();
					list.clear();
					temp.addAll(mjpegview.getListOfShapeRed());
					for(ShapeData sd : temp){
						if(sd.getShape() == type){
							list.add(sd);
						}
					}
				}
				temp.clear();
				temp = null;

				for(ShapeData sd : list){
					point[0] += sd.getX();
					point[1] += sd.getY();
					numberofShape++;
				}

				if(numberofShape != 0){
					point[0] = point[0]/numberofShape;
					point[1] = point[1]/numberofShape;
				}
			}
			list.clear();
			list = null;
			if(numberofShape > 0){
				return point;

			}
			else return null;
		}
		else if(getMODE().equals("COLOR")){
			int numberofShape = 0, point[] = {0,0};
			List<ShapeData> liste = null;

			//Start coordinate
			MjpegView mjpegview = (MjpegView) findViewById(mjpegview_id);
			if(mjpegview == null) ;
			else {
				if(type == ShapeData.BLUE){
					liste = mjpegview.getListOfShapeBlue();
				}
				else if(type == ShapeData.GREEN){
					liste = mjpegview.getListOfShapeGreen();
				}
				else if(type == ShapeData.RED){
					liste = mjpegview.getListOfShapeRed();
				}
				if(liste != null){
					for(ShapeData sd : liste){
						point[0] += sd.getX();
						point[1] += sd.getY();
						numberofShape++;
					}
				}
				if(numberofShape != 0){
					point[0] = point[0]/numberofShape;
					point[1] = point[1]/numberofShape;
				}
			}
			if(numberofShape > 0){
				return point;

			}
			else return null;
		}
		return null;
	}

	/**
	 * @return String shape
	 */
	public String getShape() {
		return shape;
	}

	/**
	 * @param String shape The shape to set
	 */
	public void setShape(String shape) {
		this.shape = shape;
	}
	/**
	 * Set the picture of shapes buttons displayed at screen
	 * @param final ShapeData sd
	 * @param final int camId
	 * @param final int button
	 */
	public void setButtonBackground(final ShapeData sd, final int camId, final int button){
		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				if(camId == CAMERA[0]){
					if(sd.getColor() == ShapeData.RED){
						switch (sd.getShape()) {
						case ShapeData.CIRCLE:
							findViewById(button).setBackgroundResource(R.drawable.circle_button_red);
							findViewById(button).setVisibility(View.VISIBLE);
							break;
						case ShapeData.SQUARE:
							findViewById(button).setBackgroundResource(R.drawable.square_button_red);
							findViewById(button).setVisibility(View.VISIBLE);
							break;
						case ShapeData.TRIANGLE:
							findViewById(button).setBackgroundResource(R.drawable.triangle_button_red);
							findViewById(button).setVisibility(View.VISIBLE);
							break;

						default:
							findViewById(button).setVisibility(View.GONE);
							break;
						}
					}
					else if(sd.getColor() == ShapeData.BLUE){
						switch (sd.getShape()) {
						case ShapeData.CIRCLE:
							findViewById(button).setBackgroundResource(R.drawable.circle_button_blue);
							findViewById(button).setVisibility(View.VISIBLE);
							break;
						case ShapeData.SQUARE:
							findViewById(button).setBackgroundResource(R.drawable.square_button_blue);
							findViewById(button).setVisibility(View.VISIBLE);
							break;
						case ShapeData.TRIANGLE:
							findViewById(button).setBackgroundResource(R.drawable.triangle_button_blue);
							findViewById(button).setVisibility(View.VISIBLE);
							break;

						default:
							findViewById(button).setVisibility(View.GONE);
							break;
						}
					}
					else if(sd.getColor() == ShapeData.GREEN){
						switch (sd.getShape()) {
						case ShapeData.CIRCLE:
							findViewById(button).setBackgroundResource(R.drawable.circle_button_green);
							findViewById(button).setVisibility(View.VISIBLE);
							break;
						case ShapeData.SQUARE:
							findViewById(button).setBackgroundResource(R.drawable.square_button_green);
							findViewById(button).setVisibility(View.VISIBLE);
							break;
						case ShapeData.TRIANGLE:
							findViewById(button).setBackgroundResource(R.drawable.triangle_button_green);
							findViewById(button).setVisibility(View.VISIBLE);
							break;

						default:
							findViewById(button).setVisibility(View.GONE);
							break;
						}
					}
					else
						findViewById(button).setVisibility(View.GONE);

					switch(button){
					case R.id.button1:
						setButton1_shape(sd);
						break;
					case R.id.button2:
						setButton2_shape(sd);
						break;
					case R.id.button3:
						setButton3_shape(sd);
						break;
					default:
						break;
					}

					if(findViewById(R.id.button1).getVisibility() == View.GONE && findViewById(R.id.button2).getVisibility() == View.GONE && findViewById(R.id.button3).getVisibility() == View.GONE){
						TextView tv = (TextView) findViewById(R.id.choice_text);
						tv.setText(getString(R.string.shape_choice)+"\n"+getString(R.string.gameFinished));
					}
				}

			}
		});
	}
	/**
	 * Dynamic creation of a MjpegView
	 * @param integer id
	 * @return LinearLayout
	 */
	public LinearLayout createAView(int id){
		//Creation of the LinearLayout of the view
		LinearLayout mjpegLayout = new LinearLayout(this);
		mjpegLayout.setBackgroundColor(Color.TRANSPARENT);
		LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT , LinearLayout.LayoutParams.WRAP_CONTENT ); 
		params.setMargins(2, 2, 2, 2);
		mjpegLayout.setLayoutParams(params); 

		//Creation of the MjegView
		MjpegView mjpegView = new MjpegView(this);
		mjpegView.setId(66642+id);
		LinearLayout.LayoutParams mjpegParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT , LinearLayout.LayoutParams.WRAP_CONTENT );
		mjpegParams.weight = 1;

		mjpegLayout.addView(mjpegView);
		return mjpegLayout;
	}

	/**
	 * @return the mODE
	 */
	public String getMODE() {
		return MODE;
	}
	/**
	 * @param mODE the mODE to set
	 */
	public void setMODE(String mODE) {
		MODE = mODE;
	}
	/**
	 * @return the uRL
	 */
	public String[] getURL() {
		return URL;
	}
	/**
	 * @param uRL the uRL to set
	 */
	public void setURL(String uRL[]) {
		URL = uRL;
	}
	/**
	 * @param uRL the uRL to set
	 */
	public void setURL(String URL,int id) {
		getURL()[id] = URL;
	}
	/**
	 * @return the popUpDisplayed
	 */
	public boolean isPopUpDisplayed() {
		return popUpDisplayed;
	}
	/**
	 * @param popUpDisplayed the popUpDisplayed to set
	 */
	public void setPopUpDisplayed(boolean popUpDisplayed) {
		this.popUpDisplayed = popUpDisplayed;
	}
	/**
	 * @return the button1_shape
	 */
	public ShapeData getButton1_shape() {
		return button1_shape;
	}
	/**
	 * @param button1_shape the button1_shape to set
	 */
	public void setButton1_shape(ShapeData button1_shape) {
		this.button1_shape = button1_shape;
	}
	/**
	 * @return the button2_shape
	 */
	public ShapeData getButton2_shape() {
		return button2_shape;
	}
	/**
	 * @param button2_shape the button2_shape to set
	 */
	public void setButton2_shape(ShapeData button2_shape) {
		this.button2_shape = button2_shape;
	}
	/**
	 * @return the button3_shape
	 */
	public ShapeData getButton3_shape() {
		return button3_shape;
	}
	/**
	 * @param button3_shape the button3_shape to set
	 */
	public void setButton3_shape(ShapeData button3_shape) {
		this.button3_shape = button3_shape;
	}

	/**
	 * @return the armControl
	 */
	public ArmControl getArmControl() {
		return armControl;
	}

	/**
	 * @param armControl the armControl to set
	 */
	public void setArmControl(ArmControl armControl) {
		this.armControl = armControl;
	}

	/**
	 * @return the centerListCam1
	 */
	public List<ShapeData> getCenterListCam1() {
		return centerListCam1;
	}

	/**
	 * @param centerListCam1 the centerListCam1 to set
	 */
	public void setCenterListCam1(List<ShapeData> centerListCam1) {
		this.centerListCam1 = centerListCam1;
	}

	/**
	 * @return the centerListCam2
	 */
	public List<ShapeData> getCenterListCam2() {
		return centerListCam2;
	}

	/**
	 * @param centerListCam2 the centerListCam2 to set
	 */
	public void setCenterListCam2(List<ShapeData> centerListCam2) {
		this.centerListCam2 = centerListCam2;
	}

	/**
	 * @return the surfaceSize
	 */
	public int[] getSurfaceSize() {
		return surfaceSize;
	}

	/**
	 * @param surfaceSize the surfaceSize to set
	 */
	public void setSurfaceSize(int[] surfaceSize) {
		this.surfaceSize = surfaceSize;
	}

	/**
	 * @return the sDrawer
	 */
	public SlidingDrawer getsDrawer() {
		return sDrawer;
	}

	/**
	 * @return the isLeftPresent
	 */
	public boolean isLeftPresent() {
		return isLeftPresent;
	}

	/**
	 * @return the isMiddlePresent
	 */
	public boolean isMiddlePresent() {
		return isMiddlePresent;
	}

	/**
	 * @return the isRightPresent
	 */
	public boolean isRightPresent() {
		return isRightPresent;
	}
}